#!/usr/bin/python2.4
#
#Copyright 2009 Google Inc.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
#


"""Tests for the module request_handler."""

import logging
import re
import unittest
import constants
import db_utils
import id_encryption
from metadata_handler import UploadMetadataHandler
from metadata_in_memory import MetadataInMemory
from page_tree_creator import PageTreeCreator
from request_handler import ReqHandler
from sorting_column_sets import SetManager
import text_data_reader
from tree_node import PageTree
import digital_content_wizard_exceptions


class Request(object):
  """Dummy Request class."""
  uri = ''
  url = ''
  path = ''
  version_id = None

  def SetVersionId(self, version_id):
    """Sets version_id.

    Args:
      version_id: Version id number.
    """
    self.version_id = version_id

  def get(self, param):
    """Dummy GET method that sets version_id parameter.

    Args:
      param: Parameter name string.
    Returns:
      Parameter value string.
    """
    if param == 'version_id':
      return self.version_id


class Response(object):
  """Dummy Response class."""

  class Out(object):
    """Dummy Out class for the Response object."""
    text = ''

    def write(self, st):
      """Dummy write response method.

      Args:
        st: String html response.
      """
      self.text = st

  def set_status(self, code):
    """Sets response status code.

    Args:
      code: Status code number.
    """
    self.status_code = code

  def clear(self):
    """Dummy clear method."""
    pass
  status_code = ''
  out = Out()


class ReqHandlerTest(unittest.TestCase):
  """Tests ReqHandler class."""

  def setUp(self):
    """Set up method."""
    logging.info('TEST: ' + self.id())
    self.metadata_in_memory = MetadataInMemory()
    self.page_tree = PageTree()
    self.db_handler = db_utils.DbHandler()
    self.set_manager = SetManager()

  def tearDown(self):
    self.set_manager.Clear()

  def PrepareDb(self, version_id):
    """Writes metadata in db.

    Args:
      version_id: Version id number.
    """
    f = open('test/data/metadata_valid.txt', 'r')
    text_data_reader.ReadMetadataFile(f, version_id)
    f.close()
    self.metadata_in_memory.UpdateMetadata({}, {}, {})
    self.upload_metadata_handler = UploadMetadataHandler()
    self.upload_metadata_handler.request = Request()
    self.upload_metadata_handler.request.uri = 'http://localhost:8080'
    self.upload_metadata_handler.response = Response()
    self.upload_metadata_handler.get()
    while True:
      out_text = self.upload_metadata_handler.response.out.text
      if out_text.find('/uploadmetadata') != -1:
        self.upload_metadata_handler = UploadMetadataHandler()
        self.upload_metadata_handler.request = Request()
        self.upload_metadata_handler.request.uri = 'http://localhost:8080'
        self.upload_metadata_handler.response = Response()
        self.upload_metadata_handler.get()
      else:
        return

  def PrepareSite(self, version_id):
    """Write GlobalData and prepares basic site.

    Args:
      version_id: Version id number.
    """
    f = open('test/data/global_valid.txt', 'r')
    text_data_reader.GetGlobalData(f, version_id)
    f.close()
    self.page_tree_creator = PageTreeCreator()
    self.page_tree_creator.request = Request()
    self.page_tree_creator.response = Response()
    self.page_tree_creator.request.uri = 'http://localhost:8080'
    if self.set_manager.IsSetEmpty(3):
      self.db_handler.UpdateNumberOfLevels(version_id, 2)
    else:
      self.db_handler.UpdateNumberOfLevels(version_id, 3)
    self.db_handler.UpdateStatus(constants.GENERATE_WEBSITE)
    self.page_tree_creator.get()
    self.set_manager.Clear()
    self.metadata_in_memory.Clear()
    return

  def testGetPage(self):
    """Test GetPage method."""
    text = '<title>Read Books - An Imprint of Books</title>'
    version_id = self.db_handler.CreateNewVersion()
    self.PrepareDb(version_id)
    self.PrepareSite(version_id)
    self.request_handler = ReqHandler()
    self.request_handler.request = Request()
    self.request_handler.response = Response()
    # No published version.
    self.request_handler.request.path = '/'
    self.request_handler.get()
    self.assertEqual(self.request_handler.response.out.text, None)
    # Invalid encypted version.
    self.request_handler.request.path = '/aaaaa/main.html'
    try:
      self.request_handler.get()
    except digital_content_wizard_exceptions.EncryptionException:
      pass
    else:
      self.fail('EncryptionException expected.')
    self.assertEqual(self.request_handler.response.out.text, None)
    # Invalid page_url: should return error code 404.
    self.request_handler.response.status_code = ''
    request_path = '/' + id_encryption.Encrypt(version_id) + '/random.html'
    self.request_handler.request.path = request_path
    self.request_handler.get()
    self.assertEqual(self.request_handler.response.out.text, None)
    self.assertEqual(self.request_handler.response.status_code, 404)
    # Version id in url.
    encrypted_version = id_encryption.Encrypt(version_id)
    self.request_handler.request.path = '/' + encrypted_version + '/main.html'
    self.request_handler.get()
    self.assertNotEqual(self.request_handler.response.out.text, None)
    self.assert_(re.search(text, self.request_handler.response.out.text))
    # Published version.
    self.db_handler.PublishVersion(version_id)
    self.request_handler.get()
    self.assertNotEqual(self.request_handler.response.out.text, None)
    self.assert_(re.search(text, self.request_handler.response.out.text))
    # Landing page.
    f = open('test/data/metadata_valid.txt', 'r')
    f.readline()
    f.readline()
    f.readline()
    columns = text_data_reader.ReadLine(f.readline())
    page_url = '/' + columns[0] + '.html'
    self.request_handler.request.path = page_url.encode('utf-8')
    self.request_handler.request.url = page_url.encode('utf-8')
    self.request_handler.get()
    self.assertNotEqual(self.request_handler.response.out.text, None)
    self.request_handler.response.out.text = ''
    self.request_handler.get()
    self.assertNotEqual(self.request_handler.response.out.text, None)
    # Clearing the version.
    self.db_handler.RemoveVersion(version_id)
    self.db_handler.RemoveVersion(version_id)
    self.db_handler.RemoveVersion(version_id)


def main(unused_argv):
  unittest.main()
